package cn.turboinfo.fuyang.api.scheduler.listener.product

import cn.turboinfo.fuyang.api.domain.common.service.product.ProductService
import cn.turboinfo.fuyang.api.domain.common.service.shop.HousekeepingShopService
import cn.turboinfo.fuyang.api.entity.common.constant.EventConstants
import cn.turboinfo.fuyang.api.entity.common.enumeration.product.ProductStatus
import cn.turboinfo.fuyang.api.entity.common.event.product.ProductStatusChangedEvent
import cn.turboinfo.fuyang.api.provider.common.component.event.EventHelper
import cn.turboinfo.fuyang.api.provider.common.constant.GeoConstants
import cn.turboinfo.fuyang.api.provider.common.service.geo.GeoService
import cn.turboinfo.fuyang.api.provider.rabbit.constant.RabbitConstants
import mu.KotlinLogging
import org.springframework.amqp.core.Binding
import org.springframework.amqp.core.BindingBuilder
import org.springframework.amqp.core.Queue
import org.springframework.amqp.core.TopicExchange
import org.springframework.amqp.rabbit.annotation.RabbitHandler
import org.springframework.amqp.rabbit.annotation.RabbitListener
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.stereotype.Component
import java.math.BigDecimal

@Configuration
class ProductGeoChangedListenerConfig(
    private val eventHelper: EventHelper,
) {

    companion object {
        private const val Name = "ProductGeoChanged"

        private const val Topic = EventConstants.TopicProductStatusChangedEvent

        const val QueueName =
            "${RabbitConstants.QueueEventPrefix}${Topic}.${Name}"

        const val RoutingKey = "${RabbitConstants.RoutingKeyEventPrefix}${Topic}"
    }


    @Bean
    fun productGeoChangedQueue(): Queue {
        return Queue(QueueName)
    }

    @Bean
    protected fun productGeoChangedBinding(
        productGeoChangedQueue: Queue,
        eventExchange: TopicExchange
    ): Binding {
        return BindingBuilder.bind(productGeoChangedQueue)
            .to(eventExchange)
            .with(RoutingKey)
    }

    @Component
    @RabbitListener(queues = [QueueName])
    class ProductGeoChangedListener(
        private val productService: ProductService,
        private val housekeepingShopService: HousekeepingShopService,
        private val geoService: GeoService,
    ) {

        private val logger = KotlinLogging.logger {}

        @RabbitHandler
        fun process(event: ProductStatusChangedEvent) {
            runCatching {
                event
                    .takeIf {
                        it.status == ProductStatus.PUBLISHED || it.status == ProductStatus.OFF_SHELF
                    }
                    ?.let {
                        productService.getByIdEnsure(it.productId)
                    }
                    ?.apply {
                        if (status == ProductStatus.OFF_SHELF) {
                            // 下架删除
                            geoService.remove(GeoConstants.STORE_PRODUCT, id.toString())
                            logger.error {
                                "服务产品已下架, 删除位置信息, productId=$id"
                            }
                        } else {
                            // 上架添加 使用门店位置
                            val shop = housekeepingShopService.getByIdEnsure(shopId)
                            if (shop.longitude > BigDecimal.ZERO && shop.latitude > BigDecimal.ZERO) {
                                geoService.add(
                                    GeoConstants.STORE_PRODUCT,
                                    id.toString(),
                                    shop.longitude.toDouble(),
                                    shop.latitude.toDouble()
                                )
                                logger.error {
                                    "服务产品已发布, 维护位置信息为门店位置, productId=$id"
                                }
                            }
                        }
                    }
            }
                .onFailure {
                    logger.error(it) { "处理服务产品状态变更时维护位置信息出错" }
                }
        }

    }
}